/*
 * AccessControlList.java
 *
 * Created on July 24, 2006, 2:31 PM
 *
 * @author Francois Daniels
 */

package za.gateway.backend;

import java.util.Vector;
import za.gateway.container.AccessControlElement;
import za.gateway.io.DatabaseInterface;
import za.gateway.io.Log;
import java.sql.ResultSet;

/**
 * This class contains a list of all the access control elements stored 
 * in the database. It is responsible to retrieve and store this data 
 * from and to the database.
 *
 * @author Francois Daniels
 */
public class AccessControlList {
    /** Variables belonging to the AccessControlList class */
    
    /**
     * This is an instance of the DatabaseInterface class. It will be 
     * used by the AccessControlList class to query and retrieve data 
     * from the database.
     */
    protected DatabaseInterface Database;
    
    /**
     * This is an vector of all the access control elements stored by 
     * the system. Elements are of type AccessContolElement.
     */
    protected Vector Data;
    
    /** 
     * Thrown if the name is too short or null 
     */
    public final static int ERROR_NAME                  = 0;   
    
    /** 
     * Thrown if the password is too short or null 
     */
    public final static int ERROR_PASSWORD              = 1;
    
    /** 
     * This error is thrown when trying to add a group which is 
     * already in the system 
     */
    public final static int ERROR_ALREADY_EXISTS        = 2;
    
    /** 
     * Indicates the function was successfully executed. 
     */
    public final static int SUCCESS                     = 3;
    
    /** 
     * Indicates an invalid phone number 
     */
    public final static int ERROR_PHONE_NUMBER          = 4;
    
    /** 
     * Indicates an invalid group name 
     */
    public final static int ERROR_GROUP_NAME            = 5;
    
    /** 
     * Indicates an invalid restriction name
     */
    public final static int ERROR_RESTRICTION_NAME      = 6;
    
    /** 
     * Indicates that we could not find the element 
     */
    public final static int ERROR_CANNOT_FIND_ELEMENT   = 7;    
    
    /** Functions belonging to the AccessControlList class */    
    
    /**
     * This function will query the database for all the access control 
     * elements stored in it. It will then place all the information 
     * returned into the array of access control elements.
     */
    protected void ReadDB () {
        
        // Retrive data from the database
        ResultSet results = 
                Database.Query ("Select * from AccessControlList");        
        
        if (results == null) return;
        
        try {
            while (results.next ()) {
                
                // Store the data in out list
                Data.add (new AccessControlElement (
                        results.getObject("Name").toString (),
                        results.getObject("RestrictionName").
                        toString (),
                        results.getObject("PhoneNumber").toString ()));
            } 
        } catch (java.sql.SQLException Ex) {
            Log.ERROR(Ex);
        }
        
        try {
            results.close ();
        } catch (Exception e) {}
    }
    
    /**
     * This function will commit all the data stored in this class to 
     * the database.
     */
    public void Save () {
        int size = Data.size();
         
         for (int i = 0; i < size; i++) {
             AccessControlElement element = (AccessControlElement) 
             Data.elementAt(i);
             if (element.IsDirty()) {
                 // Access Control Elements CAN NOT be dirty
             } else {
                 // We store the data into the database
                 Database.Update("INSERT INTO AccessControlList(Name, "
                         +"RestrictionName, PhoneNumber) VALUES ('"+
                         element.GetGroupName ()+"', '"+
                         element.GetRestrictionName ()+"', '"+
                         element.GetPhoneNumber ()+"')");
             }
         }
    }
    
    /**
     * This function will return the list of access control element 
     * stored in this class.
     *
     * @return The list of access control elements.
     */
    public AccessControlElement [] GetData () {
        return (AccessControlElement []) Data.toArray (
                new AccessControlElement [Data.size ()]);
    }
    
    /**
     * Adds a new access control element to the system.
     *
     * @param GroupName         This is the name of the group to which 
     *                          this access control element is applies
     * @param RestrictionName   This is the name of the restriction 
     *                          which is to be applied to the given 
     *                          phone number for this group.
     * @param PhoneNumber       This is the number onto which to apply 
     *                          the restriction.
     * @return                  The exit status of the function.
     */
    public int Add (String GroupName, String RestrictionName,
            String PhoneNumber) {
        
        // We do some sanity checks
        if (GroupName == null || GroupName.length () == 0)
            return ERROR_GROUP_NAME;
        
        if (RestrictionName == null || RestrictionName.length () == 0)
            return ERROR_RESTRICTION_NAME;
        
        if (PhoneNumber == null || PhoneNumber.length () == 0)
            return ERROR_PHONE_NUMBER;
            
        AccessControlElement element = 
                new AccessControlElement (GroupName, RestrictionName, 
                    PhoneNumber);
        
        // We only add this element if it is not already in our list
        if (Data.contains (element))
            return ERROR_ALREADY_EXISTS;
        
        Data.add (element);
        return SUCCESS;
    }
    
    /**
     * Removes an access control element to the system.
     *
     * @param GroupName         This is the name of the group to which
     *                          this access control element is applies.
     * @param RestrictionName   This is the name of the restriction 
     *                          which is to be applied to the given 
     *                          phone number for this group.
     * @param PhoneNumber       This is the number onto which to apply 
     *                          the restriction.
     * @return                  The exit status of the function.
     */
    public int Remove (String GroupName, String RestrictionName, 
            String PhoneNumber) {
        
        // We do some sanity checks
        if (GroupName == null || GroupName.length () == 0)
            return ERROR_GROUP_NAME;
        
        if (RestrictionName == null || RestrictionName.length () == 0)
            return ERROR_RESTRICTION_NAME;
        
        if (PhoneNumber == null || PhoneNumber.length () == 0)
            return ERROR_PHONE_NUMBER;
            
        AccessControlElement element = 
                new AccessControlElement (GroupName, RestrictionName, 
                    PhoneNumber);
        
        // We can only remove an element if it is NOT in the list
        if (!Data.contains (element))
            return ERROR_CANNOT_FIND_ELEMENT;
        
        Data.remove (element);
        return SUCCESS;
    }
    
    /**
     * Creates a new instance of AccessControlList
     *
     * @param Username      The username for the SQL database.
     * @param Password      The password for the SQL database.
     * @param HostName      The hostname on which the SQL server is 
     *                      located.
     * @param DatabaseName  The name of the database schema the data 
     *                      is in.
     */
    public AccessControlList (String Username, String Password, 
            String HostName, String DatabaseName) {
        
        Database = new DatabaseInterface (Username, Password, HostName, 
                                          DatabaseName);
        Data = new Vector ();
        ReadDB ();
    }
    
}
